package djrain.lilochat.client;

import java.util.Random;

import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Projection;

import djrain.lib.ToastEx;

public class LocationHelper implements LocationListener
{
	private static final String tag = "LocationHelper";
	private String bestProvider;
	private LocationManager locationManager;

	private OnLocationChangeListener listener;
	private Context mContext;
	private Location location;
	private String gpsProvider;

	static long MINTIME = 3000;
	static float MINDISTANCE = 0f;
	static float SPEED_UNIT = 1f;
	static boolean _DEBUG = false;

	static public interface OnLocationChangeListener
	{
		public void onLocationChanged(Location location);
	}

	void setOnLocationChangeListener(OnLocationChangeListener listener)
	{
		this.listener = listener;
	}

	public Location getLocation()
	{
		return location;
	}

	public LocationHelper(Context context)
	{
		mContext = context;
		locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
		findBestProvider();
	}

	public void findBestProvider()
	{
		// if(bestProvider != null &&
		// locationManager.isProviderEnabled(bestProvider)){
		// }

		Criteria criteria = new Criteria();
		bestProvider = locationManager.getBestProvider(criteria, false);
		location = locationManager.getLastKnownLocation(bestProvider);
		Log.e("Lilo", "find best provider:" + bestProvider);
		printProvider(bestProvider);

		// if(bestProvider == null)
		{
			gpsProvider = LocationManager.GPS_PROVIDER;
			bestProvider = gpsProvider;
		}
	}

	protected void onResume()
	{
		locationManager.requestLocationUpdates(bestProvider, MINTIME, MINDISTANCE, this);
	}

	protected void onPause()
	{
		locationManager.removeUpdates(this);
	}

	public static GeoPoint location2geopoint(Location location)
	{
		if (location == null)
			return null;
		double la = location.getLatitude();
		double lo = location.getLongitude();
		int nla = (int) (la * 1000000);
		int nlo = (int) (lo * 1000000);
		return new GeoPoint(nla, nlo);
	}

	public static GeoPoint location2geopoint(double la, double lo)
	{
		int nla = (int) (la * 1000000);
		int nlo = (int) (lo * 1000000);
		return new GeoPoint(nla, nlo);
	}

	public static GeoPoint pixel2geopoint(MapView mapView, MotionEvent ev)
	{
		Projection projection = mapView.getProjection();
		return projection.fromPixels((int) ev.getX(), (int) ev.getY());
	}

	public static void geopoint2lalo(GeoPoint geoPoint, double[] lalo)
	{
		lalo[0] = geoPoint.getLatitudeE6() / 10E5;
		lalo[1] = geoPoint.getLongitudeE6() / 10E5;
	}

	public static void pixel2lalo(MapView mapView, MotionEvent ev,double[] lalo)
	{
		Projection projection = mapView.getProjection();
		GeoPoint geoPoint = projection.fromPixels((int) ev.getX(), (int) ev.getY());

		lalo[0] = geoPoint.getLatitudeE6() / 10E5;
		lalo[1] = geoPoint.getLongitudeE6() / 10E5;
	}


	public void onLocationChanged(Location location)
	{

		if (location == null)
			return;

		if (_DEBUG)
		{
			Random rand = new Random();
			location.setLatitude(this.location.getLatitude() + (rand.nextDouble() * 0.02 - 0.01));
			location.setLongitude(this.location.getLongitude() + (rand.nextDouble() * 0.02 - 0.01));
		}
		printLocation(location);

		this.location = location;

		if (listener != null)
		{
			listener.onLocationChanged(location);
		}
	}

	public void onProviderDisabled(String provider)
	{
		ToastEx.makeText(mContext, "onProviderDisabled:  " + provider);
	}

	public void onProviderEnabled(String provider)
	{
		ToastEx.makeText(mContext, "onProviderEnabled:  " + provider);
	}

	public void onStatusChanged(String provider, int status, Bundle extras)
	{
		ToastEx.makeText(mContext, "onStatusChanged:  " + provider + "," + status);
	}

	private void printLocation(Location location)
	{
		if (location == null)
		{
			Log.e(tag, "Location[unknown]");
		}
		else
		{
			Log.e(tag, "" + location.getSpeed());
			Log.e(tag, "" + location.getLongitude());
			Log.e(tag, "" + location.getLatitude());
		}
	}

	private void printProvider(String provider)
	{
		LocationProvider info = locationManager.getProvider(provider);
		StringBuilder builder = new StringBuilder();
		builder.append("LocationProvider[").append("name=").append(info.getName()).append(",enabled=").append(locationManager.isProviderEnabled(provider)).append(",getAccuracy=")
				.append(info.getAccuracy()).append(",getPowerRequirement=").append(info.getPowerRequirement()).append(",hasMonetaryCost=").append(info.hasMonetaryCost()).append(",requiresCell=")
				.append(info.requiresCell()).append(",requiresNetwork=").append(info.requiresNetwork()).append(",requiresSatellite=").append(info.requiresSatellite()).append(",supportsAltitude=")
				.append(info.supportsAltitude()).append(",supportsBearing=").append(info.supportsBearing()).append(",supportsSpeed=").append(info.supportsSpeed()).append("]");
		Log.e(tag, builder.toString());
	}

}
